<script setup lang="ts">
import { nextTick, onMounted, ref } from 'vue';
import { Button, Card, Space, Table, Tag } from 'ant-design-vue';
import type { TableColumnsType } from 'ant-design-vue';
import {
  fetchTestMessage,
  fettchProductDefinitions,
  getProductDefinitionDetail,
  trialCalculateProduct
} from '@/service/api/valuation';
import ProductDetailModal from './modules/ProductDetailModal.vue';
import ProductTrialModal from './modules/ProductTrialModal.vue';

// 通用：兼容后端返回数据被 request.transformBackendResponse 处理后（直接返回data），或未处理（包裹在data字段）
function unwrapData<T = any>(resp: any): T | null {
  if (resp === null || resp === undefined) return null as any;
  // 如果已经是数组或对象，且不含有 code/msg 等字段，默认就是数据本体
  if (Array.isArray(resp)) return resp as any;
  if (typeof resp === 'object' && !('code' in resp) && !('msg' in resp) && !('data' in resp)) return resp as any;
  // 包裹在 data
  if (resp && typeof resp === 'object' && 'data' in resp) return resp.data as any;
  return null as any;
}

// 通用：数组数据解包
function unwrapList<T = any>(resp: any): T[] {
  const data = unwrapData<T[] | T>(resp);
  if (Array.isArray(data)) return data as T[];
  return [];
}

// 产品定义接口定义
interface ProductDefinition {
  className: string;
  fullClassName: string;
  packageName: string;
  category: string;
  categoryKey: string;
  categoryType?: string;
  description: string;
  fieldCount: number;
}

// 数据状态
const loading = ref(false);
const tableData = ref<ProductDefinition[]>([]);

// 详情模态框状态
const detailVisible = ref(false);
const selectedProduct = ref<ProductDefinition | null>(null);
const productDetail = ref<any>(null);
const detailLoading = ref(false);

// 试算功能状态
const trialCalculationLoading = ref(false);
const trialData = ref<any>(null);
const trialResult = ref<any>(null);

// 试算模态框状态
const trialVisible = ref(false);
const selectedTrialProduct = ref<ProductDefinition | null>(null);
const trialProductDetail = ref<any>(null);
const trialDetailLoading = ref(false);

// 表格列定义
const columns: TableColumnsType = [
  {
    title: '产品名称',
    dataIndex: 'name',
    key: 'name',
    width: '15%'
  },
  {
    title: '产品代码',
    dataIndex: 'code',
    key: 'code',
    width: '10%'
  },
  {
    title: '描述',
    dataIndex: 'description',
    key: 'description',
    ellipsis: true,
    width: '30%'
  },
  {
    title: '字段数量',
    dataIndex: 'fieldCount',
    key: 'fieldCount',
    width: '8%'
  },
  {
    title: '包名',
    dataIndex: 'packageName',
    key: 'packageName',
    width: '25%',
    ellipsis: true
  },
  {
    title: '操作',
    key: 'action',
    width: '12%'
  }
];

// 加载产品定义列表
async function loadProductDefinitions() {
  try {
    loading.value = true;
    const response = await fettchProductDefinitions();
    tableData.value = unwrapList<ProductDefinition>(response);
    window.$message?.success(`成功扫描到 ${tableData.value.length} 个产品定义`);
  } catch (error) {
    console.error('扫描产品定义失败:', error);
    window.$message?.error('扫描产品定义失败');
    tableData.value = [];
  } finally {
    loading.value = false;
  }
}

// 查看产品定义详情
async function handleViewDetail(record: ProductDefinition) {
  selectedProduct.value = record;
  detailVisible.value = true;
  detailLoading.value = true;

  try {
    const response = await getProductDefinitionDetail(record.className);

    productDetail.value = unwrapData(response);
  } catch (error) {
    console.error('获取产品详情失败:', error);
    window.$message?.error('获取产品详情失败');
  } finally {
    detailLoading.value = false;
  }
}

// 重新扫描
async function handleRescan() {
  await loadProductDefinitions();
}

// 关闭详情模态框
async function handleDetailCancel() {
  detailVisible.value = false;
  await nextTick(); // 等待模态框关闭动画完成
  selectedProduct.value = null;
  productDetail.value = null;
  // 清空试算数据
  trialData.value = null;
  trialResult.value = null;
}

// 打开试算模态框
async function handleTrialCalculationModal(record: ProductDefinition) {
  selectedTrialProduct.value = record;
  trialVisible.value = true;
  trialDetailLoading.value = true;

  // 清空之前的试算数据
  trialData.value = null;
  trialResult.value = null;

  try {
    const response = await getProductDefinitionDetail(record.className);
    trialProductDetail.value = unwrapData(response);
  } catch (error) {
    console.error('获取产品详情失败:', error);
    window.$message?.error('获取产品详情失败');
  } finally {
    trialDetailLoading.value = false;
  }
}

// 关闭试算模态框
async function handleTrialCancel() {
  trialVisible.value = false;
  await nextTick(); // 等待模态框关闭动画完成
  selectedTrialProduct.value = null;
  trialProductDetail.value = null;
  trialData.value = null;
  trialResult.value = null;
}

// 生成随机交易数据
async function handleTrialMessage() {
  // 优先使用试算模态框的产品数据，如果没有则使用详情模态框的数据
  const currentProduct = selectedTrialProduct.value || selectedProduct.value;
  const currentProductDetail = trialProductDetail.value || productDetail.value;

  if (!currentProduct || !currentProductDetail) {
    window.$message?.error('请先选择产品');
    return;
  }

  try {
    trialCalculationLoading.value = true;

    // 从后端接口获取对应产品测试报文
    console.info('currentProduct', currentProduct);
    const productType = currentProduct.className;
    const response = (await fetchTestMessage(productType)).data;

    if (response) {
      // 解析JSON字符串为对象
      const testMessageContent = typeof response === 'string' ? JSON.parse(response) : response;
      trialData.value = testMessageContent;
      window.$message?.success('测试报文获取完成');
    } else {
      window.$message?.warning(`未找到产品类型 ${productType} 的测试报文，请联系管理员添加`);
      trialData.value = null;
    }
  } catch (error) {
    console.error('生成交易数据失败:', error);
    window.$message?.error('生成交易数据失败');
  } finally {
    trialCalculationLoading.value = false;
  }
}

// 执行模型试算
async function handleModelTrialCalculation(marketDataId: string, mappingSetId?: string, curveSetId?: string) {
  if (!trialData.value) {
    window.$message?.error('请先生成交易数据');
    return;
  }

  if (!marketDataId) {
    window.$message?.error('请先选择市场数据集');
    return;
  }

  const currentProduct = selectedTrialProduct.value || selectedProduct.value;

  if (!currentProduct) {
    window.$message?.error('请先选择产品');
    return;
  }

  try {
    trialCalculationLoading.value = true;

    // 调用后端试算接口
    const trialRequest = {
      trade: trialData.value, // 后端期望的交易报文字段名
      marketDataId, // 市场数据集ID
      mapSetId: mappingSetId || '', // 模型映射集ID，如果没有选择则传空字符串
      curveSetId: curveSetId || '' // 曲线映射集ID，如果没有选择则传空字符串
    };

    // 检查模态框是否已经关闭，避免在关闭后处理响应
    if (!trialVisible.value && !detailVisible.value) {
      console.warn('模态框已关闭，取消试算请求');
      return;
    }

    const { data: resData, error: err } = await trialCalculateProduct(trialRequest);

    // 再次检查模态框状态
    if (!trialVisible.value && !detailVisible.value) {
      console.warn('模态框已关闭，忽略试算结果');
      return;
    }

    if (resData) {
      // 后端返回的是计算结果，需要包装成前端期望的格式
      trialResult.value = {
        success: true,
        calculationTime: new Date().toLocaleString(),
        result: resData
      };
      window.$message?.success('试算完成');
    } else {
      // 处理API调用失败的情况
      trialResult.value = {
        success: false,
        error: err?.message || '试算失败'
      };
      window.$message?.error(err?.message || '试算失败');
    }
  } catch (error) {
    console.error('试算失败:', error);
    window.$message?.error(`试算失败: ${error instanceof Error ? error.message : '未知错误'}`);
    trialResult.value = {
      success: false,
      error: error instanceof Error ? error.message : '试算过程中发生错误'
    };
  } finally {
    trialCalculationLoading.value = false;
  }
}

// 清空试算数据
function clearTrialData() {
  trialData.value = null;
  trialResult.value = null;
  window.$message?.success('数据已清空');
}

// 更新试算数据
function handleUpdateTrialData(data: Record<string, any>) {
  trialData.value = data;
}

// 获取分类颜色
function getCategoryColor(category: string): string {
  const categoryColors: Record<string, string> = {
    固定收益: 'blue',
    股票: 'green',
    外汇: 'orange',
    商品: 'purple',
    其他: 'default'
  };
  return categoryColors[category] || 'default';
}

onMounted(() => {
  loadProductDefinitions();
});
</script>

<template>
  <div class="product-definition-management">
    <!-- 产品定义列表 -->
    <Card>
      <template #title>
        <div class="flex items-center justify-between">
          <span>产品定义管理</span>
          <Space>
            <Button type="primary" @click="handleRescan">
              <icon-carbon:update-now class="mr-1" />
              重新扫描
            </Button>
          </Space>
        </div>
      </template>

      <Table
        :columns="columns"
        :data-source="tableData"
        :loading="loading"
        row-key="className"
        :scroll="{ x: 800 }"
        :pagination="{
          showSizeChanger: true,
          showQuickJumper: true,
          showTotal: (total: number) => `共 ${total} 个产品定义`
        }"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'category'">
            <Tag :color="getCategoryColor(record.category)">
              {{ record.category }}
            </Tag>
          </template>
          <template v-else-if="column.key === 'fieldCount'">
            <span>{{ record.fieldCount }}</span>
          </template>
          <template v-else-if="column.key === 'action'">
            <Space>
              <Button size="small" type="link" @click="handleViewDetail(record as ProductDefinition)">查看详情</Button>
              <Button size="small" type="link" @click="handleTrialCalculationModal(record as ProductDefinition)">
                试算
              </Button>
            </Space>
          </template>
        </template>
      </Table>
    </Card>

    <!-- 产品定义详情模态框 -->
    <ProductDetailModal
      v-model:visible="detailVisible"
      :product-detail="productDetail"
      :loading="detailLoading"
      :trial-calculation-loading="trialCalculationLoading"
      :trial-data="trialData"
      :trial-result="trialResult"
      @cancel="handleDetailCancel"
    />

    <!-- 试算模态框 -->
    <ProductTrialModal
      v-model:visible="trialVisible"
      :selected-trial-product="selectedTrialProduct"
      :loading="trialDetailLoading"
      :trial-product-detail="trialProductDetail"
      :trial-calculation-loading="trialCalculationLoading"
      :trial-data="trialData"
      :trial-result="trialResult"
      :trial-request="
        trialVisible
          ? {
              trade: trialData,
              marketDataId: undefined,
              mapSetId: undefined,
              curveSetId: undefined
            }
          : null
      "
      @cancel="handleTrialCancel"
      @generate-data="handleTrialMessage"
      @clear-data="clearTrialData"
      @trial-calculation="handleModelTrialCalculation"
      @update-trial-data="handleUpdateTrialData"
    />
  </div>
</template>

<style scoped>
/* 基础工具类 */
.product-definition-management {
  padding: 16px;
}
.text-center {
  text-align: center;
}
.py-4 {
  padding: 16px 0;
}
.mt-4 {
  margin-top: 16px;
}
.flex {
  display: flex;
}
.items-center {
  align-items: center;
}
.justify-between {
  justify-content: space-between;
}
.mr-1 {
  margin-right: 4px;
}
.mb-4 {
  margin-bottom: 16px;
}
.mb-3 {
  margin-bottom: 12px;
}
.ml-2 {
  margin-left: 8px;
}
.mt-2 {
  margin-top: 8px;
}
.text-gray-500 {
  color: #6b7280;
}

/* 其他样式保持不变 */
.product-detail-container {
  display: flex;
  gap: 24px;
  min-height: 600px;
}

.left-panel {
  flex: 0 0 400px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.right-panel {
  flex: 1;
  min-width: 0;
}

.section-title {
  margin: 0 0 12px 0;
  font-size: 16px;
  font-weight: 600;
  color: #262626;
}

.basic-info-section,
.trial-section,
.fields-section {
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
  padding: 16px;
}

.trial-description {
  margin: 8px 0 0 0;
  font-size: 12px;
  color: #8c8c8c;
  text-align: center;
}

.fields-table-container {
  border: 1px solid #f0f0f0;
  border-radius: 6px;
  overflow: hidden;
}
.no-fields {
  text-align: center;
  padding: 40px 20px;
  color: #8c8c8c;
}

.trial-modal-container {
  max-height: 70vh;
  overflow-y: auto;
}

.trial-result-success,
.trial-result-error {
  border-radius: 6px;
  padding: 12px;
}

.trial-result-success {
  background: #f6ffed;
  border: 1px solid #b7eb8f;
}

.trial-result-error {
  background: #fff2f0;
  border: 1px solid #ffccc7;
}

.trial-loading {
  text-align: center;
  padding: 40px 20px;
  background: #fafafa;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
}

/* 暗色主题适配 */
.dark .trial-calculation-section,
.dark .trial-message-section,
.dark .trial-model-section,
.dark .trial-loading {
  background: #2a2a2a;
  border-color: #404040;
}

.dark .trial-data-display {
  background: #1e1e1e;
  border-color: #404040;
}
.dark .trial-data-display pre {
  color: #e6e6e6;
}
.dark .section-title {
  color: #e6e6e6;
}
.dark .basic-info-section,
.dark .trial-section,
.dark .fields-section {
  background: #1f1f1f;
  border-color: #404040;
}
.dark .fields-table-container {
  border-color: #404040;
}
.dark .trial-result-success {
  background: #162312;
  border-color: #274916;
}
.dark .trial-result-error {
  background: #2a1215;
  border-color: #58181c;
}
</style>
